package game.service;

import com.sghd.common.utils.json.JsonUtils;
import data.entity.GameRecord;
import data.entity.PK;
import data.model.PropType;
import data.service.DataService;
import game.model.ChessBoard;
import game.model.DeskPlayer;
import game.model.GameResult;
import game.model.MGame;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import network.NetServer;
import network.ServerHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Date;
import java.util.List;
import java.util.concurrent.atomic.AtomicLong;

/**
 * @author fank
 * @date 2018-08-18 14:22
 * @desc
 **/
public class PlayerService {
    private Logger logger = LoggerFactory.getLogger(getClass());
    private int deskId = -1;
    private DeskPlayer deskPlayer;
    private ChessBoard chessBoard;
    /**最后活跃时间*/
    private Date lastUpdate = new Date();
    private Channel channel;
    private int roomId;

    public PlayerService(DeskPlayer deskPlayer, Channel channel, int roomId) {
        this.deskPlayer = deskPlayer;
        this.channel = channel;
        this.roomId = roomId;
        this.chessBoard = ChessBoard.valueOf(3, 5);
    }

    public void sendMessage(int code, Object message) {
        if (getPlayerId() <= 0) {
            return;
        }
        String msg = "";
        if (message instanceof String) {
            msg = (String) message;
        } else {
            msg = JsonUtils.object2String(message);
        }
        msg = code + NetServer.MSG_SPLIT + msg + NetServer.MSG_END;
        ServerHandler.logger.debug("发送消息：{}", msg);
        channel.writeAndFlush(Unpooled.copiedBuffer(msg.getBytes()));
    }

    public DeskPlayer getDeskPlayer() {
        return deskPlayer;
    }

    public GameResult begin(boolean free, int cost, long base, AtomicLong refund, int[] refundCtrl, float refundRate) {
        synchronized (refund) {
            logger.debug("旋转之前反分池金币：{}", refund.get());
            GameResult gameResult = chessBoard.begin(free, roomId, base, refund, refundCtrl);
            gameResult.setCost(cost);
            long addFan = (long) (((cost > 0 ? cost : gameResult.getTotalBet()) * refundRate));//一定比例放入反分池
            if (addFan != 0) {
                refund.addAndGet(addFan);
                logger.debug("旋转完成反分池金币：{}", refund.get());
            }
            return gameResult;
        }
    }

    public void join(DataService dataService) {
        if (deskPlayer.getPlayerId() <= 0) {
            return;
        }
        GameRecord record = dataService.getGameRecord(PK.valueOf(roomId, getPlayerId()));
        if (record != null) {
            //还原玩家数据
            deskPlayer.setRecord(record);
        }
    }

    public void exit(DataService dataService) {
        this.deskId = -1;
        GameRecord record = deskPlayer.getRecord(PK.valueOf(roomId, getPlayerId()));
        logger.debug("玩家[{}]退出，保存玩家数据！", getPlayerId());
        dataService.saveOrUpdate(record);//保存数据
    }

    public ChessBoard getChessBoard() {
        return chessBoard;
    }

    public void setChessBoard(ChessBoard chessBoard) {
        this.chessBoard = chessBoard;
    }

    public Date getLastUpdate() {
        return lastUpdate;
    }

    public void setLastUpdate(Date lastUpdate) {
        this.lastUpdate = lastUpdate;
    }

    public boolean isOnline() {
        return channel.isActive();
    }

    public Channel getChannel() {
        return channel;
    }

    public void setChannel(Channel channel) {
        this.channel = channel;
    }

    public long getPlayerId() {
        return deskPlayer.getPlayerId();
    }

    public DeskPlayer getPlayer() {
        return deskPlayer;
    }

    public int getRoomId() {
        return roomId;
    }

    public void setRoomId(int roomId) {
        this.roomId = roomId;
    }

    public int getDeskId() {
        return deskId;
    }

    public void setDeskId(int deskId) {
        this.deskId = deskId;
    }

    /**
     * 记录小游戏
     * */
    public void record(List<MGame> games) {
        deskPlayer.setMgames(games);
    }

    public MGame getMgame() {
        List<MGame> mgames = deskPlayer.getMgames();
        if (mgames.isEmpty()) {
            return null;
        }
        return mgames.get(0);
    }

    /**
     * 是否还有未完成的小游戏
     * */
    public boolean hasMgame() {
        return !deskPlayer.getMgames().isEmpty();
    }

    public int getBetIndex() {
        return deskPlayer.getBetIndex();
    }

    public void setBetIndex(int betIdx) {
        deskPlayer.setBetIndex(betIdx);
    }

    public void change(long change) {
        deskPlayer.change(PropType.GOLD, change);
    }

    public int getCombo() {
        return deskPlayer.getCombo();
    }

    public int getBuyTimes() {
        return deskPlayer.getBuyTimes();
    }

    /**
     * 增加购买次数
     * */
    public void setBuyTimes(int buyTimes) {
        deskPlayer.setBuyTimes(buyTimes);
    }

    public void setCombo(int combo) {
        deskPlayer.setCombo(combo);
    }

    /**
     * 删除队头的小游戏
     * @return 所有的小游戏是否已经完成
     */
    public boolean removeMgame() {
        deskPlayer.getMgames().remove(0);
        return deskPlayer.getMgames().isEmpty();
    }

    public void setFreeCount(float scope) {
        deskPlayer.setFreeCount((int) scope);
    }

    public int getFreeCount() {
        return deskPlayer.getFreeCount();
    }

    public void decressFree() {
        deskPlayer.setFreeCount(deskPlayer.getFreeCount() - 1);
    }

    public long getMoney(PropType gold) {
        return deskPlayer.getMondey(gold);
    }

    public void setFreeMoney(long totalFen, boolean free) {
        deskPlayer.setFreeMoney(free ? (deskPlayer.getFreeMoney() + totalFen) : 0);
    }
}
